package com.onlyoffice.integration.aspect;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.Arrays;

/**
 * 敏捷开发 多版本参数适配
 *
 * @Author: liqichao
 * @Date: 2021/7/20 17:37
 */
@Configuration
@Aspect
@Slf4j
public class LogAspect {


    @Pointcut("execution(* com.onlyoffice.integration.documentserver.managers..*(..))")
    public void logAspect() {

    }

    @Around(value = "logAspect()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //拿到类名
        String className = joinPoint.getTarget().getClass().getName();
        // 拿到方法签名
        Signature signature = joinPoint.getSignature();
        //拿到方法名
        String methodName = signature.getName();
        //拿到参数名
        Object[] args = joinPoint.getArgs();

        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        long begin = System.currentTimeMillis();
        String shortClassName = className.substring(className.lastIndexOf("."));
        Object proceed;
        try {
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            long end = System.currentTimeMillis();
            log.error("日志记录-：{}.{}, 参数：{}，请求路径：{}，耗时：{}s，【异常原因：{}】",
                    shortClassName, methodName, Arrays.toString(args), request.getRequestURI(), (end - begin) / 1000
                    , throwable.getMessage());
            throw throwable;
        }

        long end = System.currentTimeMillis();

        log.info("日志记录-：path:{},{}.{},参数:{},返回值:{},cost：{}ms", request.getRequestURI(), shortClassName,
                methodName, Arrays.toString(args), proceed == null ? "" : URLDecoder.decode(JSONObject.toJSONString(proceed), "utf-8"),
                (end - begin));

        return proceed;
    }
}
